#include "ThreadCache.h"
#include "CentralCache.h"

// // 申请内存对象
// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].empty())
//     {
//         return _freeLists[index].pop();
//     }
//     else 
//     {
//         return FetchFromCentralCache(index, alignSize);
//     }
// }

// // 释放内存对象
// void ThreadCache::Deallocate(void* ptr, size_t size)
// {
//     assert(ptr);
//     assert(size <= MAX_BYTES);

//     // 找到映射的自由链表桶，将对象插入进去
//     size_t index = SizeClass::Index(size);
//     _freeLists[index].push(ptr);
    
//     // 当链表的长度大于一次批量申请的内存对象时，就还一部分给central cache
//     if(_freeLists[index].size() >= _freeLists[index].maxSize())
//     {
//         ListTooLong(_freeLists[index], size);
//     }
// }



// // 申请内存对象
// void* ThreadCache::Allocate(size_t size)
// {
//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     // 直接向对应的自由链表桶中申请
//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// // 释放内存对象
// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     // 找到对应的自由链表桶， 将内存插入进去
//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     // 当自由链表的长度大于一次批量申请内存对象时，还一部分给central cache
//     if(_freeLists[index].size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }



// // 申请内存对象
// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     // 直接从对应的自由链表桶里面申请内存，如果有的话
//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].pop();
//     }
//     else 
//     {
//         // 如果对应的自由链表桶中没有内存对象，直接向central cache中申请
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// // 释放内存对象
// void ThreadCache::Deallocate(void* ptr, size_t size)
// {
//     assert(obj);

//     // 找到对应的自由链表桶，直接讲内存插入进去
//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     // 如果自由链表桶的长度大于一次批量申请内存的个数时，还一部分给central cache
//     if(_freeLists[index].size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size); // 为什么这里是size，而不用alignSize?
//     }
// }


// 申请内存对象
void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return FetchFromCentralCache(index, alignSize);
    }
}

// 释放内存对象
void ThreadCache::Deallocate(void* obj, size_t size)
{
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);

    // 直接将内存对象插入到对应的自由链表中
    _freeLists[index].Push(obj);

    // 如果自由链表的长度大于一次向central cache批量申请的内存对象数量时，还一部分给central cache
    if(_freeLists[index].size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}

// 从中心缓存获取内存对象
void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    // 慢开始反馈调节算法
    // 1.最开始不回一次向central cache申请太多，因为可能用不完s浪费
    // 2.如果不断有size大小的内存对象需求，batchNum就会不断增长，直至上限
    // 3.size越大，一次向central cache要的batchNum就越少
    // 4.size越小，一次向central cache要的batchNum就越多
    size_t batchNum = std::min(SizeClass::NumMoveSize(size), _freeLists[index].MaxSize());

    if(_freeLists[index].MaxSize() == batchNum)
        _freeLists[index].MaxSize += 1;

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else 
    {
        _freeLists[index].PopRange(NextObj(start), end, actualNum - 1); // 因为start被使用了
        return start;
    }
}



void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size); // 单例模式
}



#include "ThreadCache.h"
#include "CentralCache.h"


void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index =  SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return FetchFromCentralCache(index, alignSize);
    }
}

void ThreadCache::Deallocate(void* ptr, size_t size)
{
    assert(ptr);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::_Index(size);
    _freeLists[index].Push(ptr);

    // 如果自由链表长度过长时，会释放一部分给central cache
    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}

void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1.最开始不会一次批量申请太多，可能用不完浪费
    // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
    // 3.小对象一次批量申请的上限值高
    // 4.大对象一次批量申请的上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}


void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}



#include "ThreadCache.h"
#include "CentralCache.h"

void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else 
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}

void ThreadCache::Deallocate(void* ptr, size_t size)
{
    assert(ptr);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);

    _freeLists[index].Push(ptr);

    // 如果自由链表的长度过长时，会释放一部分会central cache
    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1.最开始不会一次批量申请太多，可能用不完浪费
    // 2.如果不断有size大小的内存需求，batchNum就会不断变大，直至上限值
    // 3.小对象一次批量申请上限值高
    // 4.大对象一次批量申请上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}

void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}


#include "ThreadCache.h"
#include "CentralCache.h"


void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else 
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}


void ThreadCache::Deallocate(void* ptr, size_t size)
{
    assert(ptr);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(ptr);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1.最开始不会一次批量申请太多，可能用不完浪费
    // 2.如果不断有size大小的内存需求，那么bachNum就会不断变大，直至上限
    // 3.小对象一次批量申请上限值高
    // 4.大对象一次批量申请上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}


void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);
    
    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}




void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}


void ThreadCache::Deallocate(void* obj, size_t size)
{   
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(obj);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1.最开始不会一次批量申请太多，可能用不完浪费
    // 2.如果不断有size大小的内存需求，batchNum就会不断变大，直至上限
    // 3.小对象一次批量申请的上限值高
    // 4.大对象一次批量申请的上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}


void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}


#include "ThreadCache.h"
#include "CentralCache.h"


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* ptr, size_t size)
// {
//     assert(ptr);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(ptr);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么bachNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);
    
//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始一次不会批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return _start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index =  SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].PushRange(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请内存对象上限值高
//     // 4.大对象一次批量申请内存对象上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return nullptr;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请的上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }
    
//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }

// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会申请太多的内存，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请内存对象多
//     // 4.大对象一次批量申请内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));
//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.一次批量申请不会太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请内存对象多
//     // 4.大对象一次批量申请内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.一开始不会批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量上限值高
//     // 4.大对象一次批量上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.一开始不会批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请的内存对象多
//     // 4.大对象一次批量申请的内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nulltpr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {   
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请的上限值高
//     // 4.大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYETS);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请的内存对象的上限值高
//     // 4.大对象一次批量申请的内存对象的上限值低

//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }

// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请上限值高
//     // 4.大对象一次批量申请上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }

// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不但变大，直至上限
//     // 3.先对象一次批量申请的上限值高
//     // 4.大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, size);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         return ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1.最开始不会一次批量申请太多，可能用不完浪费
//     // 2.如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3.小对象一次批量申请的内存对象少
//     // 4.大对象一次批量申请的内存对象多
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PusRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }

// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 一开始不会批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就不会不变大，直至上限
//     // 3. 小对象一次批量申请内存对象多
//     // 4. 大对象一次批量申请内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PusRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PusRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象多
//     // 4. 大对象一次批量申请的内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PusRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }

// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的上限值高
//     // 4. 大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//         _freeLists[index].MaxSize() += 1;

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAsX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PushRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum 就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象多
//     // 4. 大对象一次批量申请的内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// // 向thread cache申请内存
// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index]._size >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象上限高
//     // 4. 大对象一次批量申请的内存对象上限低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }




// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的上限值高
//     // 4. 大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));
    
//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }

// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 最开始不会一次批量申请太多，可能用不完浪费
//     // 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 小对象一次批量申请的上限值高
//     // 大对象一次批量申请的上限值低

//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].Push(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYETS);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的上限值高
//     // 4. 大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(Nextbj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }



// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量获取的内存对象上限高
//     // 4. 大对象一次批量获取的内存对象上限低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//        return  _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }



// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 3. 小对象一次批量申请的上限值高
//     // 4. 大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }



// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请内存对象多
//     // 4. 大对象一次批量申请内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的上限高
//     // 4. 大对象一次批量申请的上限低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 3. 小对象一次批量申请的上限值高
//     // 4. 大对象一次批量申请的上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象上限值高
//     // 4. 大对象一次批量申请的内存对象上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(batchNum > 0);

//     if(batchNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象上限值高
//     // 4. 大对象一次批量申请的内存对象上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(false);
//         return nullptr;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }




// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t ailgnSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, ailgnSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(size);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象多
//     // 4. 大对象一次批量申请的内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }   
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 3. 小对象一次批量申请的内存对象少
//     // 4. 大对象一次批量申请的内存对象多
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }

// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }



// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 3. 小对象一次批量申请的内存对象上限值高
//     // 4. 大对象一次批量申请的内存对象上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }



// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     size_t alignSize = SizeClass::RoundUp(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else 
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
//     // 3. 小对象一次批量申请的内存对象多
//     // 4. 大对象一次批量申请的内存对象少
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(actualNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }



// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;

//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }


// void* ThreadCache::Allocate(size_t size)
// {
//     assert(size <= MAX_BYTES);
    
//     size_t alignSize = SizeClass::RoundUp(size);
//     size_t index = SizeClass::Index(size);

//     if(!_freeLists[index].Empty())
//     {
//         return _freeLists[index].Pop();
//     }
//     else
//     {
//         return ThreadCache::FetchFromCentralCache(index, alignSize);
//     }
// }


// void ThreadCache::Deallocate(void* obj, size_t size)
// {
//     assert(obj);
//     assert(size <= MAX_BYTES);

//     size_t index = SizeClass::Index(size);
//     _freeLists[index].Push(obj);

//     if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
//     {
//         ThreadCache::ListTooLong(_freeLists[index], size);
//     }
// }


// void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     // 慢开始反馈调节算法
//     // 1. 最开始不会一次批量申请太多，可能用不完浪费
//     // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大直至上限
//     // 3. 小对象一次批量申请的内存对象上限值高
//     // 4. 大对象一次批量申请的内存对象上限值低
//     size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

//     if(batchNum == _freeLists[index].MaxSize())
//     {
//         _freeLists[index].MaxSize() += 1;
//     }

//     void* start = nullptr;
//     void* end = nullptr;
//     size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
//     assert(batchNum > 0);

//     if(actualNum == 1)
//     {
//         assert(start == end);
//         return start;
//     }
//     else
//     {
//         _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
//         return start;
//     }
// }


// void ThreadCache::ListTooLong(FreeList& list, size_t size)
// {
//     assert(size <= MAX_BYTES);

//     void* start = nullptr;
//     void* end = nullptr;
    
//     list.PopRange(start, end, list.MaxSize());

//     CentralCache::GetInstance()->ReleaseListToSpan(start, size);
// }




void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}


void ThreadCache::Deallocate(void* obj, size_t size)
{
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(obj);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t alignSize)
{
    // 慢开始反馈调节算法
    // 1. 最开始不会一次批量申请太多，可能用不完浪费
    // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
    // 3. 小对象一次批量申请的内存对象上限值高
    // 4. 大对象一次批量申请的内存对象上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}


void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}




void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::NumMoveSize(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}



void ThreadCache::Deallocate(void* obj, size_t size)
{
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(obj);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1. 最开始不会一次批量申请太多，可能用不完浪费
    // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，zhizhishangxian
    // 3. 小对象一次批量申请的内存对象多
    // 4. 大对象一次批量申请的内存对象少
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(batchNum > 0);

    if(batchNum == 1)
    {
        assert(start == end);
        return start;
    }
    else 
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}


void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}




void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::RoundUp(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}



void ThreadCache::Deallocate(void* obj, size_t size)
{
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(obj);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}


void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1. 最开始不会一次批量申请太多，可能用不完浪费
    // 2. 如果不断有size大小的内存需求，那么batchNum就会不断变大，直至上限
    // 3. 小对象一次批量申请的内存对象上限值高
    // 4. 大对象一次批量申请的内存对象上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
        _freeLists[index].MaxSize() += 1;

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].pushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}



void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}



void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t alignSize = SizeClass::Round(size);
    size_t index = SizeClass::Index(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return ThreadCache::FetchFromCentralCache(index, alignSize);
    }
}

void ThreadCache::Deallocate(void* obj, size_t size)
{
    assert(obj);
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    _freeLists[index].Push(obj);

    if(_freeLists[index].Size() >= _freeLists[index].MaxSize())
    {
        ThreadCache::ListTooLong(_freeLists[index], size);
    }
}

void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    assert(size <= MAX_BYTES);

    // 慢开始反馈调节算法
    // 1. 最开始不会一次批量申请太多，可能用不完浪费
    // 2. 如果不断有size大小的内存需求，那么batchNum就会不断表达，直至上限
    // 3. 小对象一次批量申请的内存对象上限值高
    // 4. 大对象一次批量申请的内存对象上限值低
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));

    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, size);
    assert(actualNum > 0);
    
    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end, actualNum - 1);
        return start;
    }
}   

void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
    assert(size <= MAX_BYTES);

    void* start = nullptr;
    void* end = nullptr;

    list.PopRange(start, end, list.MaxSize());

    CentralCache::GetInstance()->ReleaseListToSpan(start, size);
}



